/**
 * @Author       : Mo 2427995270@qq.com
 * @Date         : 2025-06-03 23:06:53
 * @LastEditTime : 2025-06-12 10:47:02
 * @FilePath     : \GD32F407_BL\mobl\hal_driver\ll_spi.h
 * @Description  : spi低层驱动
 * @Version      : V1.0
 * @History      :
 * @Note         :
 */
#ifndef __ll_spi_H__
#define __ll_spi_H__

/***************************************Includes***********************************/

#include "ll_gpio.h"
#include <stdint.h>


/*************************************Public Macros********************************/




/***********************************Public Statement*******************************/

typedef enum {
    SPI_LL_DIRECTION_2LINS_FULL_DUPLEX, // 2线全双工
    SPI_LL_DIRECTION_2LINS_RXONLY,      // 2线仅接收
    SPI_LL_DIRECTION_1LINS_RX,          // 1线接收
    SPI_LL_DIRECTION_1LINS_TX,          // 1线发送
} spi_ll_direction_t;                   // spi方向选项

typedef enum {
    SPI_LL_CLK_POLARITY_LOW,  // CLK 极性低
    SPI_LL_CLK_POLARITY_HIGH, // CLK 极性高
} spi_ll_clk_polarity_t;      // CLK 极性选项

typedef enum {
    SPI_LL_PHASE_1EDGE, // 第一个跳变沿采样
    SPI_LL_PHASE_2EDGE, // 第二个跳变沿采样
} spi_ll_phase_t;       // 相位配置

typedef enum {
    SPI_LL_DATASIZE_8BIT,  // 数据大小 8bit
    SPI_LL_DATASIZE_16BIT, // 数据大小 16bit
} spi_ll_datasize_t;       // 数据大小配置

typedef enum {
    SPI_LL_FIRST_BIT_MSB, // 先传输高位
    SPI_LL_FIRST_BIT_LSB, // 先传输低位
} spi_ll_first_bit_t;     // 配置传输第一个bit

typedef enum {
    SPI_LL_MODE_MASTER, // 主模式
    SPI_LL_MODE_SLAVE,  // 从模式
} spi_ll_mode_t;        // SPI模式配置

typedef struct {
    uint32_t port_sck;                  // 时钟引脚端口
    uint32_t port_miso;                 // 输入引脚端口
    uint32_t port_mosi;                 // 输出引脚端口
    uint32_t port_nss;                  // 片选引脚端口
    uint32_t pin_sck;                   // 时钟引脚号
    uint32_t pin_miso;                  // 输入引脚号
    uint32_t pin_mosi;                  // 输出引脚号
    uint32_t pin_nss;                   // 片选引脚号
    uint32_t spix;                      // spi号
    spi_ll_direction_t direction;       // 方向配置
    spi_ll_clk_polarity_t clk_polarity; // CLK极性配置
    spi_ll_phase_t phase;               // 相位配置
    spi_ll_datasize_t datasize;         // 数据大小配置
    spi_ll_first_bit_t first_bit;       // 配置传输的第一个bit
    spi_ll_mode_t mode;                 // 模式配置
    uint32_t crc_polynomial;            // CRC多项式 0禁用crc校验，1~65535 开启crc校验
    uint32_t cfg_interrupt_priority;    // 抢占中断优先级 建议优先级分组设置为4组，4位抢占
} spi_ll_config_t;


typedef struct {
    uint32_t spix;     // SPI句柄
    uint32_t clk_freq; // 实际的spi频率
    gpio_ll_t gpio_nss;
    spi_ll_datasize_t datasize;          // 数据大小配置
    spi_ll_direction_t spi_ll_direction; // 方向
    uint32_t cfg_interrupt_priority;     // 抢占中断优先级 建议优先级分组设置为4组，4位抢占
    uint32_t port_sck;                   // 时钟引脚端口
    uint32_t port_miso;                  // 输入引脚端口
    uint32_t port_mosi;                  // 输出引脚端口
    uint32_t port_nss;                   // 片选引脚端口
    uint32_t pin_sck;                    // 时钟引脚号
    uint32_t pin_miso;                   // 输入引脚号
    uint32_t pin_mosi;                   // 输出引脚号
    uint32_t pin_nss;                    // 片选引脚号
} spi_ll_t;

/***********************************Public Functions*******************************/

/**
 * @brief spi初始化
 * @param  slt
 * @param  clk_freq         Spi频率
 * @param  config           Spi配置
 * @return int 0成功 -1失败
 * @note null
 */
int spi_ll_init(spi_ll_t *slt, uint32_t clk_freq, spi_ll_config_t *config);
/**
 * @brief spi传输和接收
 * @param  slt
 * @param  tx_data          发送的数据
 * @param  rx_data          接收的数据
 * @param  len              数据长度 1个长度对应8bit的一字节 对应16Bit的二个字节
 * @return int 0成功 -1失败
 * @note null
 */
int spi_ll_transmit_receive(spi_ll_t *slt, void *tx_data, void *rx_data, uint32_t len);
/**
 * @brief spi传输和接收一个字节
 * @param  slt
 * @param  tx_data          发送的数据
 * @return int 接收的数据
 * @note null
 */
int spi_ll_transmit_receive_byte(spi_ll_t *slt, uint16_t tx_data);
/**
 * @brief spi片选使能
 * @param  slt
 * @param  nen              0使能 1禁用
 * @return int 0成功 -1失败
 * @note null
 */
int spi_ll_chip_select_en(spi_ll_t *slt, int nen);

/***************************************Public Variables**********************************/


#endif
/* [] END OF FILE */
